var allConnections = [];
var allConnectionsAtPoint = [];
var firstConnectionItem = null;
var allSplitters = [];

var FACT_LAYER = 1, PLAN_LAYER = 2;
var selectedCables = null;
var selectedSegments = [];
var connections = null;
var paper;
var cnvs = null;

var glowElements = [];
var currentCables = [];

var showLeftSegmentID = null;
var showRightSegmentID = null;

var connectedSegmentIdInAnotherConnection = null;

function bindPoint() {
    if (pointId) {
        $.ajax({
            method: "POST",
            url: "include/connection_controller.php",
            data: {
                op: "get_point",
                id: pointId
            }
        }).done(function (response) {
            var point = JSON.parse(response);
            pointId = point.id;
            if (point.title)
                $("#point-title").text(point.title);
            $("#point-location").text(point.location);
            if (point.connection == 0)
                $("#point-type").text("Точка опоры");
            else
                $("#point-type").text("Точка соединения");

            if (point.id_type)
                $("#point-support-type").val(point.id_type);
            if (point.comment)
                $("#point-comment").text(point.comment);
            $("#point-connection").val(point.connection);
            $("#not_created").hide();
            $("#connection_div").show();
            pointLayer = parseInt(point.layer, 10);
            setPointLayer();
            fillConnectionsTable(point.connect_points);
        });
    } else {
        $("#point-type").text("Точка опоры");
        $("#point-connection").val("0");
        $("#delete-point").hide();
        $("#connection-tr").hide();
        $("#not_created").show();
        $("#connection_div").hide();
        $("#point-location").text(pointLocation);
        $("#point-location").editable();
        setPointLayer();
    }
}

function setPointLayer() {
    if (pointLayer & PLAN_LAYER)
        $("#planCheck").attr("checked", true);
    if (pointLayer & FACT_LAYER)
        $("#factCheck").attr("checked", true);
}

function getPointLayer() {
    var layer = 0;
    if ($("#planCheck").is(":checked"))
        layer += 2;
    if ($("#factCheck").is(":checked"))
        layer += 1;
    return layer;
}

function fillConnectionsTable(connections) {
    var oTable = $("#connection_points").dataTable();
    oTable.fnClearTable();
    $.each(connections, function (idx, con) {
        oTable.fnAddData([con.name, con.type, con.id]);
    });
}

function savePoint() {
    if (!pointId)
        pointId = guid();
    var point = {
        "id": pointId,
        "comment": $("#point-comment").html(),
        "title": $("#point-title").html(),
        "location": $("#point-location").text(),
        "type": $("#point-support-type").val(),
        "layer": getPointLayer()
    };

    if (point.title == editPlaceholder)
        point.title = "";
    if (point.comment == editPlaceholder)
        point.comment = "";

    $.ajax({
        method: "POST",
        url: "include/connection_controller.php",
        data: {
            op: "save_point",
            data: JSON.stringify(point)
        }
    }).done(function (response) {
        var result = JSON.parse(response);
        if (result.success)
            parent.$("body").trigger("pointSaved");
        else
            alert("Ошибка при сохранении точки: " + result.error);
    });
}

function deletePoint() {
    if (pointId && confirm("Вы действительно хотите удалить опорную точку?")) {
        $.ajax({
            method: "POST",
            url: "include/connection_controller.php",
            data: {
                op: "delete_point",
                id: pointId
            }
        }).done(function (response) {
            var result = JSON.parse(response);
            if (result.success)
                parent.$("body").trigger("pointDeleted");
            else
                alert("Ошибка при удалении точки: " + result.error);
        });
    }
}

function saveSegment() {
    if (!segmentId)
        segmentId = guid();
    var segment = {
        "length": "NULL",
        "attenuation": "NULL",
        "id": segmentId,
        "cable": $("#segment-cable").val()
    };
    if ($("#segment-factlength").html() != editPlaceholder)
        segment["length"] = $("#segment-factlength").text();
    if ($("#segment-factattenuation").html() != editPlaceholder)
        segment["attenuation"] = $("#segment-factattenuation").text();

    $.ajax({
        method: "POST",
        url: "include/connection_controller.php",
        data: {
            op: "save_segment",
            data: JSON.stringify(segment)
        }
    }).done(function (response) {
        var result = JSON.parse(response);
        if (result.success)
            parent.$("body").trigger("segmentSaved");
        else
            alert("Ошибка при сохранении сегмента: " + result.error);
    });
}

function deleteSegment() {
    if (segmentId && confirm("Вы действительно хотите удалить сегмент?")) {
        $.ajax({
            method: "POST",
            url: "include/connection_controller.php",
            data: {
                op: "delete_segment",
                id: segmentId
            }
        }).done(function (response) {
            var result = JSON.parse(response);
            if (result.success)
                parent.$("body").trigger("segmentDeleted");
            else
                alert("Ошибка при удалении сегмента: " + result.error);
        });
    }
}

function ClearGlowedCables() {
    for (var g = 0; g < glowElements.length; g++) {
        glowElements[g].remove();
    }
    glowElements = [];
}

function initConnections(id, cid, needResize) {
    var conPoint = (isNew || (cid != null)) == true;
    var viewMode = (!isNew && cid == null);
    $("#connection_info").toggle(conPoint);
    $("#merge_notice").toggle(viewMode);

    if (needResize) {
        ResizeConnectionContainerDialog();
    }

    var data = {
        id: pointId
    };
    if (cid)
        data["cid"] = cid;
    $.ajax({
        method: "POST",
        url: "include/connection_controller.php",
        data: {
            op: "get_connections",
            data: JSON.stringify(data)
        }
    }).done(function (response) {
        glowElements = [];

        currentCables = [];

        var result = JSON.parse(response);
        var location = result.location;
        var segments = result.segments;
        if (cid) {
            $("#connect_name").text(result.connect_point.name);
            $("#connect_type").text(result.connect_point.type);
        }
        result.connection = (cid || isNew);
        var rwidth = 500.0, rheight = 400.0;
        paper = Raphael($("#canvas").get(0), rwidth, rheight);
        selectedCables = paper.set();
        selectedSegments = []
        connections = paper.set();
        var r = 70;
        var circle = paper.circle(rwidth / 2, rheight / 2, r).attr("stroke", "grey").attr("stroke-dasharray", ".").attr("stroke-width", 1);
        var angles = Array();
        var ox = 0, oy = 0;
        var connectPath = {};
        var allCables = paper.set();
        if (result.connection)
            $("#editor_notice").show();
        var visited = [];
        for (var i = segments.length - 1; i >= 0; i--) {
            if (visited.indexOf(i) >= 0) continue;
            segments[i].idx = i + 1;
            visited.push(i);
            currentCables.push({ id: segments[i].id, title: i});
            var start = JSON.parse(segments[i].start_point), end = JSON.parse(segments[i].end_point);
            var group = [segments[i]];
            for (var j = 0; j < i; j++) {
                if (visited.indexOf(j) >= 0) continue;
                var jstart = JSON.parse(segments[j].start_point), jend = JSON.parse(segments[j].end_point);
                if ((start.compare(jstart) && end.compare(jend)) || (end.compare(jstart) && start.compare(jend))) {
                    visited.push(j);
                    segments[j].idx = j + 1;
                    group.push(segments[j]);
                }
            }
            var angle;
            if (segments[i].start_point == location)
                angle = Math.atan2(end[0] - start[0], end[1] - start[1]);
            else
                angle = Math.atan2(start[0] - end[0], start[1] - end[1]);
            var cx = rwidth / 2 + r * Math.cos(angle), cy = rheight / 2 - r * Math.sin(angle);
            var segSet = paper.set();
            var path = paper.path("M" + cx + "," + cy + " L" + (rwidth / 2 + 300 * Math.cos(angle)).toFixed(0) + "," + (rheight / 2 - 300 * Math.sin(angle))).attr("stroke-width", "10").attr("stroke", "#FF00FF");
            if (isNew && !cid)
                path.attr("stroke-opacity", "0.3");
            path.id = segments[i].id;
            path.segmentTitle = "S" + (i + 1);
            path.data("isSegment", true);
            path.data("group", group);
            path.cable = segments[i].cable;
            segSet.push(path);
            var segmentTitle = (group.length > 1) ? "[" + group.map(function(elem) { return "S" + elem.idx; }).sort().join(", ") + "]" : "S" + (i + 1) + "\r\n" + segments[i].cable_title;
            segSet.push(paper.text((rwidth / 2 + 180 * Math.cos(angle)).toFixed(0), (rheight / 2 - 180 * Math.sin(angle)).toFixed(0), segmentTitle).attr({ "font-size": 16, "font-family": "Arial, Helvetica, sans-serif", "font-weight": "bold" }));

            allCables.push(segSet);

            if (group.length == 1)
                path.click(function () {
                    pathClick(this);
                });
            else
                path.click(function (event, x, y) {
                    groupClick(this, x, y);
                });

            function groupClick(p, x, y) {
                var segArray = p.data("group");
                var popup = $("<div></div>").addClass("popup_segment_select");
                var innerDiv = $("<div></div>");
                $.each(segArray, function (idx, seg) {
                    if (viewMode && selectedCables.length == 1)
                        if (selectedSegments[0].cable != seg.cable || selectedSegments[0].id == seg.id)
                            return;

                    var link = $("<a href='javascript:void(0)'></a>").html("S" + seg.idx + ": " + seg.cable_title).click(function () {
                        var data = p.data();
                        p.id = seg.id;
                        p.cable = seg.cable;
                        p.segmentTitle = "S" + seg.idx;
                        p.data(data);
                        pathClick(p);
                    });
                    innerDiv.append(link).append("<br/>");
                });
                popup.append(innerDiv);
                popup.css({"left": x + "px", "top": y + "px"});
                popup.hover(function () {
                    if ($(this).is(":animated"))
                        $(this).stop().animate({opacity: '100'});
                }, function () {
                    $(this).fadeOut(1000);
                });
                $("body").append(popup);
                var bWidth = $("body").width();
                var pos =popup.position();
                if (pos.left + popup.width() > bWidth)
                    pos.left = bWidth - popup.width() - 10;
                popup.css({"left":pos.left+"px", "top": pos.top+"px"});
            }

            function pathClick(seg) {
                $("body .popup_segment_select").hide();
                ClearGlowedCables();
                if (selectedCables.length >= 2) {
                    selectedSegments = [];
                    selectedCables.clear();
                }

                if (viewMode && selectedCables.length == 1) {
                    allCables.forEach(function (p) {
                        p.show();
                    });
                    connections.forEach(function (c) {
                        c.show();
                    });
                }
                if ($.inArray(seg.id, selectedSegments.map(function (elem) {
                    return elem.id;
                })) > -1) {
                    selectedSegments = [];
                    selectedCables.clear();
                    seg.attr("stroke", "#FF00FF");
                    return;
                }

                seg.attr("stroke", "#0000FF");

                selectedCables.push(seg);
                selectedSegments.push({id: seg.id, title: seg.segmentTitle, cable: seg.cable});
                if (viewMode && selectedCables.length == 1) {
                    allCables.forEach(function (p) {
                        if ($.inArray(seg.cable, p[0].data("group").map(function(elem) { return elem.cable; })) == -1)
                            p.hide();
                    });
                    connections.forEach(function (c) {
                        c.hide();
                    });
                }
                if (selectedCables.length == 2) {
                    selectedCables.attr("stroke", "#FF00FF");
                    if (viewMode) {
                        mergeCables(selectedSegments[0].id, selectedSegments[1].id);
                    }
                    if (!viewMode) {
                        if (!CanCreateConnectionBetweenSegments(selectedSegments[0].id, selectedSegments[1].id)) {
                            window.alert("Отсутствует возможность редактирования данного соеднинения (непрерывный участок кабеля).");
                        }
                        else {
                            showConnection(selectedSegments[0].id, selectedSegments[1].id, selectedSegments[0].title, selectedSegments[1].title);
                            glowElements.push(selectedCables[0].glow(), selectedCables[1].glow());
                        }
                    }
                }
            }

            path.hover(function () {
                if (selectedCables.length == 0 || selectedCables[0] != this)
                    this.attr("stroke", "red");
            }, function () {
                if (selectedCables.length == 0 || selectedCables[0] != this)
                    this.attr("stroke", "#FF00FF");
            });
            $.each(group, function (idx, seg) {
                connectPath[seg.id] = [cx, cy];
            });
        }

        allConnectionsAtPoint = result.connections;
        var activeCables = [];

        for (var i = 0; i < result.connections.length; i++) {
            var con = result.connections[i];
            var disabled = ((cid && con.id_connect_point != cid) || (!cid && isNew));
            if (con.left_unit_type == "segment" && con.right_unit_type == "segment") {
                var newPath = drawConnection(paper, connectPath, con.left_unit, con.right_unit, true, activeCables, disabled);
                if (newPath) {
                    connections.push(newPath);
                }
            }
            else if (con.left_unit_type == "fiber" && con.right_unit_type == "fiber" && con.left_segment != con.right_segment) {
                var newPath = drawConnection(paper, connectPath, con.left_segment, con.right_segment, false, activeCables, disabled);
                if (newPath) {
                    connections.push(newPath);
                }
            }
            else if (con.left_unit_type == "splitter" && con.right_unit_type == "fiber") {
                var left_seg = getConnectedSegments(con.left_splitter, allConnectionsAtPoint);
                for (var k = 0; k < left_seg.length; k++) {
                    if (con.right_segment != left_seg[k]) {
                        var newPath = drawConnection(paper, connectPath, con.right_segment, left_seg[k], false, activeCables, disabled);
                        if (newPath) {
                            connections.push(newPath);
                        }
                    }
                }
            }
            else if (con.right_unit_type == "splitter" && con.left_unit_type == "fiber") {
                var right_segs = getConnectedSegments(con.right_splitter, allConnectionsAtPoint);
                for (var k = 0; k < right_segs.length; k++) {
                    if (con.left_segment != right_segs[k]) {
                        var newPath = drawConnection(paper, connectPath, con.left_segment, right_segs[k], false, activeCables, disabled);
                        if (newPath) {
                            connections.push(newPath);
                        }
                    }
                }
            }
            else if (con.right_unit_type == "splitter" && con.left_unit_type == "splitter") {
                var left = getConnectedSegments(con.left_splitter, allConnectionsAtPoint);
                var right = getConnectedSegments(con.right_splitter, allConnectionsAtPoint);
                for (var k = 0; k < left.length; k++) {
                    for (var l = 0; l < right.length; l++) {
                        if (left[k] != right[l]) {
                            var newPath = drawConnection(paper, connectPath, left[k], right[l], false, activeCables, disabled);
                            if (newPath) {
                                connections.push(newPath);
                            }
                        }
                    }
                }
            }
        }

        if (cid)
            allCables.forEach(function (obj) {
                if ($.inArray(obj[0].id, activeCables) < 0)
                    obj[0].attr("stroke-opacity", "0.3");
            });

        $(".editable_single").editable();
    });
}

function CanCreateConnectionBetweenSegments(idUnit1, idUnit2) {
    var result = false;
    $.ajax({
        method: "POST",
        url: "include/connection_controller.php",
        data: {
            op: "can_create_connection_between_segments",
            unit1: idUnit1,
            unit2: idUnit2,
            pointID: pointId
        },
        async: false
    }).done(function (response) {
        var parsed = JSON.parse(response);
        result = parsed.success;
    });
    return result;
}

function labelPath(pathObj, text, textattr) {
    if (textattr == undefined)
        textattr = { 'font-size': 10, fill: '#000', stroke: 'none', 'font-family': 'Arial,Helvetica,sans-serif', 'font-weight': 400 };
    var bbox = pathObj.getBBox();
    debugger;
    var textObj = pathObj.paper.text(bbox.x + bbox.width / 2, bbox.y + bbox.height / 2, text).attr(textattr);
    return textObj;
}

function getConnectedSegments(splitter, all_connections) {
    var segments = [];
    $.each(all_connections, function (i, val) {
        if (val.left_unit_type == "splitter" && val.left_splitter == splitter) {
            if (val.right_unit_type == "splitter") {
                var newArr = all_connections.slice();
                newArr.splice(i, 1);
                union_arrays(segments, getConnectedSegments(val.right_splitter, newArr));
            }
            else if (val.right_unit_type == "fiber")
                segments.push(val.right_segment);
        }
        else if (val.right_unit_type == "splitter" && val.right_splitter == splitter) {
            if (val.left_unit_type == "splitter") {
                var newArr = all_connections.slice();
                newArr.splice(i, 1);
                union_arrays(segments, getConnectedSegments(val.left_splitter, newArr));
            }
            else if (val.left_unit_type == "fiber")
                segments.push(val.left_segment);
        }
    });
    return $.unique(segments);
}

function drawConnection(paper, connectPath, left, right, full, activeCables, disabled) {
    var isExist = false;
    for (var z = 0; z < connections.length; z++) {
        if (connections[z].id == left + "," + right || connections[z].id == right + "," + left) {
            isExist = true;
            break;
        }
    }
    if (!isExist) {
        var first = connectPath[left], second = connectPath[right];
        var cx = first[0], cy = first[1];
        var ox = second[0], oy = second[1];
        var path = paper.path("M" + ox + " " + oy + " Q250 200 " + cx + " " + cy).attr("stroke-width", 4).attr("stroke", "black");
        if (!full) {
            path.attr("stroke-dasharray", ["-"]);
        }
        else if (full && !disabled) {
            path.hover(function () {
                this.attr("stroke", "yellow");
            }, deselectCollections);
            path.click(function () {
                var ids = this.id.split(',');
                DeleteConnectionBetweenSegments(ids[0], ids[1]);
            });
        }

        path.id = left + "," + right;

        if (disabled || !full)
            path.attr("stroke-opacity", "0.3");
        else {
            if ($.inArray(left, activeCables) < 0)
                activeCables.push(left);
            if ($.inArray(right, activeCables) < 0)
                activeCables.push(right);
        }
        return path;
    }
    else {
        return null;
    }
}

function deselectCollections() {
    connections.attr("stroke", "black");
}

function GetColorSetOnItem(item) {
    var result = item;
    if (item.type != "rect") {
        cnvs.getElementsByPoint(item.attr("x"), item.attr("y")).forEach(function (el) {
            if (el.type == "rect") {
                result = el;
            }
        });
    }

    return result;
}

function GetConnectedSegmentIdInAnotherConnection(currentSegmentID1, currentSegmentID2, colorSet) {
    showLeftSegmentID = currentSegmentID1;
    showRightSegmentID = currentSegmentID2;

    for (var i = 0; i < allConnections.length; i++) {
        if (allConnections[i].leftUnit.type == "fiber" && allConnections[i].leftUnit.segmentID == colorSet.data("segmentID") && allConnections[i].leftUnit.fiberID == colorSet.data("fiberID")) {
            if (allConnections[i].rightUnit.type == "fiber") {
                return allConnections[i].rightUnit.segmentID;
            }
        }
        else if (allConnections[i].leftUnit.type == "splitter" && allConnections[i].leftUnit.splitterID == colorSet.data("splitterID") && allConnections[i].leftUnit.isInput == colorSet.data("isInput") &&
            allConnections[i].leftUnit.number == colorSet.data("number")) {
            if (allConnections[i].rightUnit.type == "fiber") {
                return allConnections[i].rightUnit.segmentID;
            }
        }
        else if (allConnections[i].rightUnit.type == "fiber" && allConnections[i].rightUnit.segmentID == colorSet.data("segmentID") && allConnections[i].rightUnit.fiberID == colorSet.data("fiberID")) {
            if (allConnections[i].leftUnit.type == "fiber") {
                return allConnections[i].leftUnit.segmentID;
            }
        }
        else if (allConnections[i].rightUnit.type == "splitter" && allConnections[i].rightUnit.splitterID == colorSet.data("splitterID") && allConnections[i].rightUnit.isInput == colorSet.data("isInput") &&
            allConnections[i].rightUnit.number == colorSet.data("number")) {
            if (allConnections[i].leftUnit.type == "fiber") {
                return allConnections[i].leftUnit.segmentID;
            }
        }
    }

    return null;
}

function showConnection(id1, id2, title1, title2) {
    $("#connection_window").css("display", "table");
    var div = $("#cnvsConnection").html("");
    ResizeConnectionContainerDialog();

    $.ajax({
        method: "POST",
        url: "include/connection_controller.php",
        data: {
            "op": "get_struct",
            "data": JSON.stringify({
                "point": pointId,
                "segment1": id1,
                "segment2": id2
            })
        }
    }).done(function (response) {
        var res = JSON.parse(response);
        var width = 600;
        var height = 380;

        allSplitters = [];
        allConnections = [];

        showLeftSegmentID = showRightSegmentID = firstConnectionItem = connectedSegmentIdInAnotherConnection = null;

        cnvs = Raphael(div[0], width, height);

        for (var i = 0; i < res.segments.length; i++) {
            var segmentOffset = (i == 0) ? 60 : width - 60;
            cnvs.text(segmentOffset, 10, "Сегмент " + eval("title" + (i + 1).toString())).attr({ "font-size": 18, "font-family": "Arial, Helvetica, sans-serif", "font-weight": "bold" });

            var moduleOffset = (i == 0) ? 60 : width - 55;
            var moduleColorOffset = i == 0 ? moduleOffset + 43 : moduleOffset - 63;
            var fiberOffset = (i == 0) ? 40 : width - 30;
            var fiberColorOffset = i == 0 ? fiberOffset + 10 : fiberOffset - 30;

            var modules = ConvertObjectPropertiesToArray(res.segments[i].modules);

            for (var j = 0, lastModuleVerticalCoordinate = 0, lastFiberVerticalCoordinate = 0; j < modules.length; j++) {
                var module = modules[j];
                var moduleVerticalOffset = lastFiberVerticalCoordinate == 0 ? 30 : lastFiberVerticalCoordinate + 17;

                lastModuleVerticalCoordinate = cnvs.text(moduleOffset, moduleVerticalOffset, "Модуль " + module.number).attr({ "font-size": 16, "font-family": "Arial, Helvetica, sans-serif", "font-weight": "bold" }).attr("y");
                var moduleColorElement = cnvs.rect(moduleColorOffset, moduleVerticalOffset - 4, 20, 10).attr({
                    "stroke": "black",
                    "fill": "#" + module.color.split("#")[1]
                });
                if (parseInt(module.color.split("#")[0]) > 0) {
                    cnvs.text(moduleColorElement.attr("x") + 10, moduleColorElement.attr("y") + 8, "*").attr({
                        "font-size": "18",
                        "font-weight": "bold"
                    });
                }

                for (var k = 0, lastFiberVerticalCoordinate = 0; k < module.fibers.length; k++) {
                    var fiber = module.fibers[k];
                    var fiberVerticalOffset = lastFiberVerticalCoordinate == 0 ? 20 + lastModuleVerticalCoordinate : lastFiberVerticalCoordinate + 15;

                    lastFiberVerticalCoordinate = cnvs.text(fiberOffset, fiberVerticalOffset, fiber.number).attr({ "font-size": 14, "font-family": "Arial, Helvetica, sans-serif", "font-weight": "bold" }).attr("y");

                    var fiberColorSet = cnvs.set();
                    var fiberColorElement = cnvs.rect(fiberColorOffset, fiberVerticalOffset - 5, 20, 10).attr({ "stroke": "black" });

                    if (fiberColorElement.attr("y") + fiberColorElement.attr("height") > cnvs.height) {
                        cnvs.setSize(cnvs.width, cnvs.height + fiberColorElement.attr("height") + 17);
                    }

                    if (IsConnectedFiberInOtherConnectionPoint(res.segments[i].id, fiber.id)) {
                        CreateExistedConnectionLabel({ coord: GetEndPointCoordinate(fiberColorElement, width), type: "fiber" });
                        fiberColorElement.data("isConnectedInOtherConnectionPoint", true);
                    }

                    fiberColorSet.push(fiberColorElement);

                    if (fiber.color.search("[0-9]#") != -1) {
                        fiberColorElement.attr("fill", "#" + fiber.color.split("#")[1]);
                        if (parseInt(fiber.color.split("#")[0]) > 0) {
                            fiberColorSet.push(cnvs.text(fiberColorElement.attr("x") + 10, fiberColorElement.attr("y") + 8, "*").attr({
                                "font-size": "18",
                                "font-weight": "bold"
                            }));
                        }
                    }
                    else {
                        fiberColorElement.attr("fill", fiber.color);
                    }

                    fiberColorSet.forEach(function (el) {
                        el.data("fiberID", fiber.id).data("segmentID", res.segments[i].id).data("type", "fiber");
                    });

                    fiberColorSet.hover(function () {
                            this.attr({ "cursor": "pointer" });

                            var conItem = GetConnectionItemByFiber(this.data("segmentID"), this.data("fiberID"));
                            if (conItem) {
                                HoverHandler_ColorSet(conItem, true);
                            }
                        },
                        function () {
                            var conItem = GetConnectionItemByFiber(this.data("segmentID"), this.data("fiberID"));
                            if (conItem) {
                                HoverHandler_ColorSet(conItem, false);
                            }
                        });

                    fiberColorSet.click(function () {
                        var colorSet = GetColorSetOnItem(this);

                        if (colorSet.data("isConnectedInOtherConnectionPoint")) {
                            connectedSegmentIdInAnotherConnection = GetConnectedSegmentIdInAnotherConnection(id1, id2, this);
                            if (connectedSegmentIdInAnotherConnection) {
                                var currentFiberSide = (colorSet.attr("x") < (width / 2)) ? "left" : "right";
                                $("#divShowNewConnection").data("isSplitter", false).data("currentFiberSide", currentFiberSide).dialog("open");
                                return;
                            }
                            else {
                                window.alert("Данный элемент участвует в соединении в точке, отличной от данной!");
                                return;
                            }

                        }

                        if (firstConnectionItem == null) {
                            firstConnectionItem = CreateFirstConnectedFiberItem(this, width, colorSet);
                        }
                        else {
                            if (firstConnectionItem.type == "fiber" && firstConnectionItem.colorSet != colorSet && !IsConnectedFiber(allConnections, firstConnectionItem.segmentID, firstConnectionItem.fiberID) && !IsConnectedFiber(allConnections, this.data("segmentID"), this.data("fiberID")) && !IsConnectedFiberInOtherConnectionPoint(this.data("segmentID"), this.data("fiberID")) && !IsConnectedFiberInOtherConnectionPoint(firstConnectionItem.segmentID, firstConnectionItem.fiberID)) {
                                var leftDrawItem =
                                {
                                    type: "fiber",
                                    coord: GetEndPointCoordinate(this, width),
                                    colorSet: colorSet
                                };

                                var rightDrawItem =
                                {
                                    type: "fiber",
                                    coord: {x: firstConnectionItem.x, y: firstConnectionItem.y},
                                    colorSet: firstConnectionItem.colorSet
                                };

                                var line = DrawConnectionLine(leftDrawItem, rightDrawItem);

                                var conItem =
                                {
                                    line: line,
                                    leftUnit: null,
                                    rightUnit: null
                                };

                                var left = {
                                    type: "fiber",
                                    segmentID: firstConnectionItem.segmentID,
                                    fiberID: firstConnectionItem.fiberID
                                };
                                var right = {
                                    type: "fiber",
                                    segmentID: this.data("segmentID"),
                                    fiberID: this.data("fiberID")
                                };
                                conItem.leftUnit = left;
                                conItem.rightUnit = right;
                                allConnections.push(conItem);

                                firstConnectionItem.glowElement.remove();
                                firstConnectionItem = null;
                            }
                            else if (firstConnectionItem.type == "splitter" && !IsConnectedFiber(allConnections, this.data("segmentID"), this.data("fiberID")) && !IsConnectedFiberInOtherConnectionPoint(this.data("segmentID"), this.data("fiberID")) && !IsConnectedSplitterItem(allConnections, firstConnectionItem.splitterID, firstConnectionItem.isInput, firstConnectionItem.number)) {
                                var leftDrawItem =
                                {
                                    type: "splitter",
                                    coord: { x: firstConnectionItem.x, y: firstConnectionItem.y},
                                    isInput: firstConnectionItem.isInput,
                                    colorSet: firstConnectionItem.colorSet
                                };

                                var rightDrawItem =
                                {
                                    type: "fiber",
                                    coord: GetEndPointCoordinate(this, width),
                                    colorSet: colorSet
                                };

                                var line = DrawConnectionLine(leftDrawItem, rightDrawItem);

                                var conItem = {
                                    line: line,
                                    leftUnit: {
                                        type: "splitter",
                                        splitterID: firstConnectionItem.splitterID,
                                        isInput: firstConnectionItem.isInput,
                                        number: firstConnectionItem.number
                                    },
                                    rightUnit: {
                                        type: "fiber",
                                        segmentID: this.data("segmentID"),
                                        fiberID: this.data("fiberID")
                                    }
                                };
                                allConnections.push(conItem);
                                firstConnectionItem.glowElement.remove();
                                firstConnectionItem = null;
                            }
                            else {
                                window.alert("Конфликт соединения!");
                                firstConnectionItem.glowElement.remove();
                                firstConnectionItem = null;
                            }
                        }
                    });
                }
            }
        }

        DrawConnections(allConnections);
    });
}

function ShowNewConnection(onSide, isSplitter, currentFiberSide) {
    if (showLeftSegmentID && showRightSegmentID && connectedSegmentIdInAnotherConnection) {
        var newLeftID, newRightID = null;
        if (isSplitter) {
            if (onSide == "left") {
                newLeftID = connectedSegmentIdInAnotherConnection;
                newRightID = showRightSegmentID;
            }
            else {
                newLeftID = showLeftSegmentID;
                newRightID = connectedSegmentIdInAnotherConnection;
            }
        }
        else {
            if (currentFiberSide == "left") {
                if (onSide == "left") {
                    newLeftID = showLeftSegmentID;
                    newRightID = connectedSegmentIdInAnotherConnection;
                }
                else {
                    newRightID = showLeftSegmentID;
                    newLeftID = connectedSegmentIdInAnotherConnection;
                }
            }
            else {
                if (onSide == "left") {
                    newLeftID = showRightSegmentID;
                    newRightID = connectedSegmentIdInAnotherConnection;
                }
                else {
                    newRightID = showRightSegmentID;
                    newLeftID = connectedSegmentIdInAnotherConnection;
                }
            }
        }

        selectedCables.clear();
        selectedSegments = [];
        ClearGlowedCables();
        paper.forEach(function (el) {
            if (el.data("isSegment")) {
                var arrIndex = $.inArray(newLeftID, el.data("group").map(function(elem) { return elem.id; }));
                if (arrIndex > -1) {
                    var seg = el.data("group")[arrIndex];
                    glowElements.push(el.glow());
                    selectedCables.push(el);
                    selectedSegments.push({id: seg.id, title: "S" + seg.idx, cable: seg.cable});
                }
            }
        });
        paper.forEach(function (el) {
            if (el.data("isSegment")) {
                var arrIndex = $.inArray(newRightID, el.data("group").map(function(elem) { return elem.id; }));
                if (arrIndex > -1) {
                    var seg = el.data("group")[arrIndex];
                    glowElements.push(el.glow());
                    selectedCables.push(el);
                    selectedSegments.push({id: seg.id, title: "S" + seg.idx, cable: seg.cable});
                }
            }
        });

        showConnection(selectedSegments[0].id, selectedSegments[1].id, selectedSegments[0].title, selectedSegments[1].title);
    }
}

function HoverHandler_ColorSet(conItem, isHoverOn) {
    var strokeLine = isHoverOn ? "#E9B28E" : "#9DB28E";
    var colorSetLine = isHoverOn ? "#E9B28E" : "black";
    var colorSetStrokeWidth = isHoverOn ? 2 : 1;

    if (conItem.line) {
        conItem.line.attr({ "stroke": strokeLine });
        HighlightConnectionLinesAndSplitterOnHover(conItem.line, isHoverOn);
    }

    if (conItem.leftUnit.type == "fiber") {
        var item = GetFiberColorSet(conItem.leftUnit.segmentID, conItem.leftUnit.fiberID);
        if (item) {
            item.attr({ "stroke": colorSetLine, "stroke-width": colorSetStrokeWidth });
        }
    }
    else if (conItem.leftUnit.type == "splitter") {
        var item = GetSplitterItemColorSet(conItem.leftUnit.splitterID, conItem.leftUnit.isInput, conItem.leftUnit.number);
        if (item) {
            item.attr({ "stroke": colorSetLine, "stroke-width": colorSetStrokeWidth });
        }
    }

    if (conItem.rightUnit.type == "fiber") {
        var item = GetFiberColorSet(conItem.rightUnit.segmentID, conItem.rightUnit.fiberID);
        if (item) {
            item.attr({ "stroke": colorSetLine, "stroke-width": colorSetStrokeWidth });
        }
    }
    else if (conItem.rightUnit.type == "splitter") {
        var item = GetSplitterItemColorSet(conItem.rightUnit.splitterID, conItem.rightUnit.isInput, conItem.rightUnit.number);
        if (item) {
            item.attr({ "stroke": colorSetLine, "stroke-width": colorSetStrokeWidth });
        }
    }
}

function SplitterAdded() {
    $.ajax({
        method: "POST",
        url: "include/splitter_controller.php",
        data: {
            op: "get_splitter_type_info",
            id: $("#divSelectSplitter #ddlSplitterType option:selected").val()
        },
        async: false
    }).done(function (response) {
        var data = JSON.parse(response);
        var info = data.splitter;
        var newItem = CreateSplitterObject(info.title, info.id, info.inputs, info.outputs, info.id, info.attenuation, data.attenuations);
        DrawSplitter(newItem);
    });
}

function DeleteSplitterAndBoundedConnections(splitterID) {
    for (var i = 0; i < allSplitters.length; i++) {
        if (allSplitters[i].splitterID == splitterID) {
            if (allSplitters[i].set) {
                allSplitters[i].set.remove();
            }
            allSplitters.splice(i, 1);
            break;
        }
    }

    for (var i = 0; i < allConnections.length; i++) {
        var conItem = allConnections[i];
        if ((conItem.leftUnit.type == "splitter" && conItem.leftUnit.splitterID == splitterID) ||
            (conItem.rightUnit.type == "splitter" && conItem.rightUnit.splitterID == splitterID)) {
            if (conItem.line) {
                conItem.line.remove();
            }

            allConnections.splice(i, 1);
            i--;
        }
    }
}

function GetConnectionItemByFiber(segmentID, fiberID) {
    for (var i = 0; i < allConnections.length; i++) {
        if ((allConnections[i].leftUnit.type == "fiber" && allConnections[i].leftUnit.segmentID == segmentID && allConnections[i].leftUnit.fiberID == fiberID) ||
            (allConnections[i].rightUnit.type == "fiber" && allConnections[i].rightUnit.segmentID == segmentID && allConnections[i].rightUnit.fiberID == fiberID)) {
            return allConnections[i];
        }
    }

    return null;
}

function GetConnectionItemBySplitterInputOutput(splitterID, isInput, number) {
    for (var i = 0; i < allConnections.length; i++) {
        if ((allConnections[i].leftUnit.type == "splitter" && allConnections[i].leftUnit.splitterID == splitterID && allConnections[i].leftUnit.isInput == isInput && allConnections[i].leftUnit.number == number) ||
            (allConnections[i].rightUnit.type == "splitter" && allConnections[i].rightUnit.splitterID == splitterID && allConnections[i].rightUnit.isInput == isInput && allConnections[i].rightUnit.number == number)) {
            return allConnections[i];
        }
    }

    return null;
}

function DrawSplitter(splitter) {
    allSplitters.push(splitter);

    var minimalWidth = 170;

    var splitterSet = cnvs.set();

    var x = cnvs.width / 2;
    var bottomSplitter = GetBottomSplitter();
    var verticalOffset = bottomSplitter.y + bottomSplitter.height + 20;

    var splitterTitle = splitter.title;
    var headerText = cnvs.text(x, verticalOffset, splitterTitle);
    headerText.attr({ "font-size": 12, "font-family": "Arial, Helvetica, sans-serif", "font-weight": "bold" });

    var evalWidth = (headerText.node.clientWidth / 2 + 5 + 13 + 5) * 2;
    var splitterWidth = evalWidth > minimalWidth ? evalWidth : minimalWidth;

    var header = cnvs.rect(x - splitterWidth / 2, headerText.attr("y") - 9, splitterWidth, 20);
    header.attr({"stroke": "black", "fill": "#cccccc"});

    var btnDelete = cnvs.set();
    var btnDeleteBody = cnvs.rect(header.attr("x") + header.attr("width") - 17, headerText.attr("y") - 5.4, 13, 13, 2);
    btnDeleteBody.attr({"fill": "#e6e6e6"});
    var btnDeleteText = cnvs.text(btnDeleteBody.attr("x") + 6.5, btnDeleteBody.attr("y") + 5.5, "x");
    btnDeleteText.attr({"font-size": 12, "font-weight": "bold", "font": "#888888"});
    btnDelete.push(btnDeleteBody, btnDeleteText);

    btnDelete.hover(function () {
        btnDelete.attr({"cursor": "pointer", "title": "Удалить сплиттер"});
    });

    btnDelete.click(function () {
        DeleteSplitterAndBoundedConnections(splitter.splitterID);
    });

    headerText.insertAfter(header);
    btnDelete.insertAfter(header);

    var body = cnvs.rect(x - splitterWidth / 2, header.attr("y") + header.attr("height"), splitterWidth, (splitter.outputs + 1) * 15);
    body.attr({"stroke": "black", "fill": "#F0F0F0"});

    var divider = cnvs.path("M" + (x - 20) + "," + body.attr("y") + " L" + (x - 20) + "," + (body.attr("y") + body.attr("height")));
    divider.attr({"stroke": "black", "stroke-width": 1});

    var inputVerticalOffset = (body.attr("height") / 2 + body.attr("y")) - (splitter.inputs * 10 - 5);
    for (var i = 1; i < splitter.inputs + 1; i++) {
        var horizontalOffset = x - splitterWidth / 2 + 18;
        var input = cnvs.rect(horizontalOffset, inputVerticalOffset, 20, 10);
        AddDataToSplitterInputOutput(input, splitter, true, i);

        var textInput = cnvs.text(horizontalOffset + 30, inputVerticalOffset + 5, i).attr({ "font-size": 14, "font-family": "Arial, Helvetica, sans-serif", "font-weight": "bold" });
        inputVerticalOffset += 15;

        splitterSet.push(input, textInput);
    }

    var outputVerticalOffset = header.attr("y") + header.attr("height");
    for (var i = 1; i < splitter.outputs + 1; i++) {
        var horizontalOffset = x + splitterWidth / 2 - 38;
        outputVerticalOffset = i == 1 ? outputVerticalOffset + 10 : outputVerticalOffset + 15;
        var output = cnvs.rect(horizontalOffset, outputVerticalOffset, 20, 10);
        AddDataToSplitterInputOutput(output, splitter, false, i);

        var text = i + " (" + (splitter.directAttenuation != null ? splitter.directAttenuation : splitter.attenuations[i - 1].attenuation) + ")";
        var textOutput = cnvs.text(horizontalOffset, outputVerticalOffset + 5, text).attr({
            "font-size": 14,
            "font-family": "Arial, Helvetica, sans-serif",
            "font-weight": "bold",
            "title": "Затухание на данном выходе"
        });
        textOutput.attr("x", horizontalOffset - ((textOutput.node.getNumberOfChars() * 6) / 2) - 5);
        textOutput.hover(function () {
            this.attr("cursor", "help");
        });

        splitterSet.push(output, textOutput);
    }

    splitterSet.push(header, headerText, body, divider, btnDelete);

    splitter.x = header.attr("x");
    splitter.y = header.attr("y");
    splitter.height = header.attr("height") + body.attr("height");

    splitter.set = splitterSet;


    if (splitter.y + splitter.height > cnvs.height) {
        cnvs.setSize(cnvs.width, cnvs.height + splitter.height + 10);
    }
}

function AddDataToSplitterInputOutput(item, splitter, isInput, number) {
    item.attr({ "stroke": "black", "fill": "white" });
    item.data({"type": "splitter",
        "splitterID": splitter.splitterID,
        "isInput": isInput,
        "number": number
    })

    item.hover(function () {
        this.attr({ "cursor": "pointer" });

        var conItem = GetConnectionItemBySplitterInputOutput(this.data("splitterID"), this.data("isInput"), this.data("number"));
        if (conItem) {
            HoverHandler_ColorSet(conItem, true);
        }

    }, function () {
        var conItem = GetConnectionItemBySplitterInputOutput(this.data("splitterID"), this.data("isInput"), this.data("number"));
        if (conItem) {
            HoverHandler_ColorSet(conItem, false);
        }
    });

    item.click(function () {
        if (this.data("isConnectedInOtherConnectionPoint")) {
            connectedSegmentIdInAnotherConnection = GetConnectedSegmentIdInAnotherConnection(selectedSegments[0].id, selectedSegments[1].id, this);
            if (connectedSegmentIdInAnotherConnection) {
                $("#divShowNewConnection").data("isSplitter", true).dialog("open");
                return;
            }
            else {
                window.alert("Данный элемент участвует в соединении в точке, отличной от данной!");
                return;
            }
        }

        if (firstConnectionItem == null) {
            firstConnectionItem = CreateFirstConnectedSplitterItem(item, splitter);
        }
        else {
            if (firstConnectionItem.type == "fiber" && !IsConnectedFiber(allConnections, firstConnectionItem.segmentID, firstConnectionItem.fiberID) && !IsConnectedFiberInOtherConnectionPoint(firstConnectionItem.segmentID, firstConnectionItem.fiberID) && !IsConnectedSplitterItem(allConnections, this.data("splitterID"), this.data("isInput"), this.data("number"))) {
                var leftDrawItem = {
                    type: firstConnectionItem.type,
                    coord: { x: firstConnectionItem.x, y: firstConnectionItem.y},
                    colorSet: firstConnectionItem.colorSet
                };
                var rightDrawItem = {
                    type: "splitter",
                    coord: GetEndPointCoordinate_SplitterItem(this),
                    isInput: this.data("isInput"),
                    colorSet: this
                }
                var line = DrawConnectionLine(leftDrawItem, rightDrawItem);

                var conItem = {
                    line: line,
                    leftUnit: {
                        type: "fiber",
                        segmentID: firstConnectionItem.segmentID,
                        fiberID: firstConnectionItem.fiberID
                    },
                    rightUnit: {
                        type: "splitter",
                        splitterID: this.data("splitterID"),
                        isInput: this.data("isInput"),
                        number: this.data("number")
                    }
                };
                allConnections.push(conItem);
                firstConnectionItem.glowElement.remove();
                firstConnectionItem = null;
            }
            else if (firstConnectionItem.type == "splitter" && firstConnectionItem.splitterID != this.data("splitterID") && !IsConnectedSplitterItem(allConnections, firstConnectionItem.splitterID, firstConnectionItem.isInput, firstConnectionItem.number) && !IsConnectedSplitterItem(allConnections, this.data("splitterID"), this.data("isInput"), this.data("number"))) {
                var leftDrawItem =
                {
                    coord: { x: firstConnectionItem.x, y: firstConnectionItem.y},
                    type: "splitter",
                    isInput: firstConnectionItem.isInput,
                    colorSet: firstConnectionItem.colorSet
                };

                var rightDrawItem = {
                    coord: GetEndPointCoordinate_SplitterItem(this),
                    type: "splitter",
                    isInput: this.data("isInput"),
                    colorSet: this
                };

                var line = DrawConnectionLine(leftDrawItem, rightDrawItem);
                var conItem = {
                    line: line,
                    leftUnit: {
                        type: "splitter",
                        splitterID: firstConnectionItem.splitterID,
                        isInput: firstConnectionItem.isInput,
                        number: firstConnectionItem.number
                    },
                    rightUnit: {
                        type: "splitter",
                        splitterID: this.data("splitterID"),
                        isInput: this.data("isInput"),
                        number: this.data("number")
                    }
                };

                allConnections.push(conItem);
                firstConnectionItem.glowElement.remove();
                firstConnectionItem = null;
            }
            else {
                window.alert("Конфликт соединения!");
                firstConnectionItem.glowElement.remove();
                firstConnectionItem = null;
            }
        }
    });

    return item;
}

function DrawConnections(allConnections) {
    $.ajax({
        method: "POST",
        url: "include/connection_controller.php",
        data: {
            "op": "get_connections_at_point",
            "connection_point_id": cid
        }
    }).done(function (response) {
        var result = JSON.parse(response);
        if (result.success) {
            for (var i = 0; i < result.connections.length; i++) {
                var con = result.connections[i];

                var leftDrawItem = null;
                var leftConItem = null;
                if (con.left_unit_type == 'fiber') {
                    leftConItem = {
                        type: con.left_unit_type,
                        segmentID: con.left_unit_segmentID,
                        fiberID: con.left_unit_fiberID
                    };

                    var left = GetFiberColorSet(con.left_unit_segmentID, con.left_unit_fiberID);
                    if (left) {
                        leftDrawItem = {
                            type: con.left_unit_type,
                            coord: GetEndPointCoordinate(left, cnvs.width),
                            colorSet: left
                        };
                    }
                }
                else if (con.left_unit_type == "splitter") {
                    var splitterObject = AddAndDrawSplitterOnDemand(con.left_unit_splitterID);
                    var isInput = con.left_unit_splitterInput == "1" ? true : false;
                    var left = GetSplitterItemColorSet(splitterObject.splitterID, isInput, con.left_unit_splitterNumber);
                    if (left) {
                        leftDrawItem = {
                            type: "splitter",
                            coord: GetEndPointCoordinate_SplitterItem(left),
                            isInput: isInput,
                            colorSet: left
                        };
                    }

                    leftConItem = {
                        splitterID: splitterObject.splitterID,
                        isInput: isInput,
                        number: con.left_unit_splitterNumber,
                        type: "splitter"
                    };
                }

                var rightDrawItem = null;
                var rightConItem = null;
                if (con.right_unit_type == "fiber") {
                    var right = GetFiberColorSet(con.right_unit_segmentID, con.right_unit_fiberID);
                    if (right) {
                        rightDrawItem = {
                            type: con.right_unit_type,
                            coord: GetEndPointCoordinate(right, cnvs.width),
                            colorSet: right
                        };
                    }

                    rightConItem = {
                        type: con.right_unit_type,
                        segmentID: con.right_unit_segmentID,
                        fiberID: con.right_unit_fiberID
                    }
                }
                else if (con.right_unit_type == "splitter") {
                    var isInput = con.right_unit_splitterInput == "1" ? true : false;
                    var splitterObject = AddAndDrawSplitterOnDemand(con.right_unit_splitterID);
                    var right = GetSplitterItemColorSet(splitterObject.splitterID, isInput, con.right_unit_splitterNumber);
                    if (right) {
                        rightDrawItem = {
                            type: "splitter",
                            coord: GetEndPointCoordinate_SplitterItem(right),
                            isInput: isInput,
                            colorSet: right
                        };
                    }

                    rightConItem = {
                        type: "splitter",
                        splitterID: splitterObject.splitterID,
                        isInput: isInput,
                        number: con.right_unit_splitterNumber
                    };
                }

                var line = null;
                if (leftDrawItem && rightDrawItem) {
                    line = DrawConnectionLine(leftDrawItem, rightDrawItem);
                }
                else if (leftDrawItem == null && rightDrawItem) {
                    var lblAlert = CreateExistedConnectionLabel(rightDrawItem);

                    if (rightConItem.type == "splitter") {
                        for (var j = 0; j < allSplitters.length; j++) {
                            if (allSplitters[j].splitterID == rightConItem.splitterID) {
                                allSplitters[j].set.push(lblAlert);
                            }
                        }
                        GetSplitterItemColorSet(rightConItem.splitterID, rightConItem.isInput, rightConItem.number).data("isConnectedInOtherConnectionPoint", true);
                    }
                    else if (rightConItem.type == "fiber") {
                        GetFiberColorSet(rightConItem.segmentID, rightConItem.fiberID).data("isConnectedInOtherConnectionPoint", true);
                    }
                }
                else if (rightDrawItem == null && leftDrawItem) {
                    var lblAlert = CreateExistedConnectionLabel(leftDrawItem);

                    if (leftConItem.type == "splitter") {
                        for (var j = 0; j < allSplitters.length; j++) {
                            if (allSplitters[j].splitterID == leftConItem.splitterID) {
                                allSplitters[j].set.push(lblAlert);
                            }
                        }
                        GetSplitterItemColorSet(leftConItem.splitterID, leftConItem.isInput, leftConItem.number).data("isConnectedInOtherConnectionPoint", true);
                    }
                    else if (leftConItem.type == "fiber") {
                        GetFiberColorSet(leftConItem.segmentID, leftConItem.fiberID).data("isConnectedInOtherConnectionPoint", true);
                    }
                }

                var conItem =
                {
                    line: line,
                    leftUnit: leftConItem,
                    rightUnit: rightConItem
                };
                allConnections.push(conItem);
            }
        }
        else {
            window.alert(result.error);
        }
    });
}

function AddAndDrawSplitterOnDemand(id) {
    for (var i = 0; i < allSplitters.length; i++) {
        if (allSplitters[i].splitterID == id) {
            return allSplitters[i];
        }
    }

    var data = GetSplitterInfo(id);
    var info = data.splitter;
    var newItem = CreateSplitterObject(info.typeTitle, info.typeID, info.inputs, info.outputs, info.id, info.attenuation, data.attenuations);
    DrawSplitter(newItem);

    return newItem;
}

function GetBottomSplitter() {
    var item = {
        x: 0,
        y: 0,
        height: 0
    };

    for (var i = 0; i < allSplitters.length; i++) {
        if (allSplitters[i].y && allSplitters[i].height && (allSplitters[i].y + allSplitters[i].height) > (item.y + item.height)) {
            item.x = allSplitters[i].x;
            item.y = allSplitters[i].y;
            item.height = allSplitters[i].height;
        }
    }

    return item;
}

function CreateSplitterObject(title, typeID, inputs, outputs, id, directAttenuation, attenuations) {
    var splitter = {
        title: title,
        typeID: typeID,
        inputs: parseInt(inputs),
        outputs: parseInt(outputs),
        splitterID: id,
        directAttenuation: directAttenuation,
        attenuations: attenuations
    };

    return splitter;
}

function GetSplitterInfo(id) {
    var splitter;
    $.ajax({
        method: "POST",
        url: "include/splitter_controller.php",
        data: {
            op: "get_splitter_info",
            id: id
        },
        async: false
    }).done(function (response) {
        splitter = JSON.parse(response);
    });

    return splitter;
}

function CreateExistedConnectionLabel(item) {
    var x;
    if (item.type == "fiber")
        x = (item.coord.x < cnvs.width / 2) ? item.coord.x + 8 : item.coord.x - 8;
    else if (item.type == "splitter")
        x = item.isInput ? item.coord.x - 8 : item.coord.x + 8;

    var txt = cnvs.text(x, item.coord.y, "X");
    txt.attr({
        "font-size": 14,
        "font-family": "Arial, Helvetica, sans-serif",
        "font-weight": "bold",
        "fill": "red",
        "title": "Данный элемент уже участвует в соединении.",
        "cursor": "help"
    });

    return txt;
}

function GetFiberColorSet(segmentID, fiberID) {
    var item = null;
    cnvs.forEach(function (el) {
        if (el.data("segmentID") == segmentID && el.data("fiberID") == fiberID && el.type == "rect") {
            item = el;
            return;
        }
    });

    return item;
}

function GetSplitterItemColorSet(splitterID, isInput, number) {
    var item = null;

    cnvs.forEach(function (el) {
        if (el.data("type") == "splitter" && el.data("splitterID") == splitterID && el.data("isInput") == isInput && el.data("number") == number) {
            item = el;
            return;
        }
    });

    return item;
}

function IsConnectedFiberInOtherConnectionPoint(segmentID, fiberID) {
    for (var i = 0; i < allConnectionsAtPoint.length; i++) {
        var con = allConnectionsAtPoint[i];
        if (cid != con.cid && ((con.left_unit_type == "fiber" && con.left_segment == segmentID && con.left_fiber == fiberID) ||
            (con.right_unit_type == "fiber" && con.right_segment == segmentID && con.right_fiber == fiberID)))
            return true;
    }

    return false;
}

function IsConnectedFiber(connections, segmentID, fiberID) {
    for (var i = 0; i < connections.length; i++) {
        if ((connections[i].leftUnit.type == "fiber" && connections[i].leftUnit.segmentID == segmentID && connections[i].leftUnit.fiberID == fiberID) ||
            (connections[i].rightUnit.type == "fiber" && connections[i].rightUnit.segmentID == segmentID && connections[i].rightUnit.fiberID == fiberID))
            return true;
    }

    return false;
}

function IsConnectedSplitterItem(connections, splitterID, isInput, number) {
    for (var i = 0; i < connections.length; i++) {
        if ((connections[i].leftUnit.type == "splitter" && connections[i].leftUnit.splitterID == splitterID && connections[i].leftUnit.isInput == isInput && connections[i].leftUnit.number == number) ||
            (connections[i].rightUnit.type == "splitter" && connections[i].rightUnit.splitterID == splitterID && connections[i].rightUnit.isInput == isInput && connections[i].rightUnit.number == number))
            return true;
    }

    return false;
}

function RemoveFromConnectionArray(connections, line) {
    for (var i = 0; i < connections.length; i++) {
        if (connections[i].line == line) {
            connections.splice(i, 1);
            i--;
        }
    }
}

function GetEndPointCoordinate(item, width) {
    if (item.type == 'rect' && (item.attr("x") < width / 2)) {
        return {
            x: item.attr("x") + 21,
            y: item.attr("y") + 5
        };
    }
    else if (item.type == 'rect' && (item.attr("x") > width / 2)) {
        return {
            x: item.attr("x") - 1,
            y: item.attr("y") + 5
        };
    }
    else if (item.type == 'text' && (item.attr("x") > width / 2)) {
        return {
            x: item.attr("x") - 11,
            y: item.attr("y") - 3
        };
    }
    else if (item.type == 'text' && (item.attr("x") < width / 2)) {
        return {
            x: item.attr("x") + 11,
            y: item.attr("y") - 3
        };
    }
}

function GetEndPointCoordinate_SplitterItem(item) {
    if (item.data("isInput")) {
        return {
            x: item.attr("x") - 1,
            y: item.attr("y") + 5
        }
    }
    else {
        return {
            x: item.attr("x") + 21,
            y: item.attr("y") + 5
        }
    }
}

function CreateFirstConnectedFiberItem(item, width, colorSet) {
    var coord = GetEndPointCoordinate(item, width);

    var conItem = {
        type: "fiber",
        segmentID: item.data("segmentID"),
        fiberID: item.data("fiberID"),
        x: coord.x,
        y: coord.y,
        glowElement: colorSet.glow(),
        colorSet: colorSet
    };

    return conItem;
}

function CreateFirstConnectedSplitterItem(item, splitter) {
    var coord = GetEndPointCoordinate_SplitterItem(item);

    var conItem = {
        type: "splitter",
        splitterID: splitter.splitterID,
        isInput: item.data("isInput"),
        number: item.data("number"),
        x: coord.x,
        y: coord.y,
        glowElement: item.glow(),
        colorSet: item
    };

    return conItem;
}

function HighlightConnectionLinesAndSplitterOnHover(line, needHideOtherConnections) {
    var value = needHideOtherConnections ? 0.3 : 1;
    var currentConItem = null;
    for (var i = 0; i < allConnections.length; i++) {
        var conItem = allConnections[i];
        if (line && conItem.line && conItem.line != line) {
            SetOpaciteAttribute(conItem.line, value);
        }
        else if (line && conItem.line && line == conItem.line) {
            currentConItem = conItem;
        }
    }

    if (currentConItem) {
        for (var i = 0; i < allSplitters.length; i++) {
            if ((currentConItem.leftUnit.type == "splitter" && currentConItem.leftUnit.splitterID == allSplitters[i].splitterID) ||
                (currentConItem.rightUnit.type == "splitter" && currentConItem.rightUnit.splitterID == allSplitters[i].splitterID)) {
                //SetOpaciteAttribute(allSplitters[i].set, )
            }
            else {
                SetOpaciteAttribute(allSplitters[i].set, value);
            }
        }
    }

    if (needHideOtherConnections) {
        line.forEach(function (el) {
            if (el.data("isMain")) {
                el.toFront();
            }
        });
    }
    else {
        line.forEach(function (el) {
            if (el.data("isMain")) {
                el.toBack();
            }
        });
    }
}

function SetOpaciteAttribute(elementSet, value) {
    for (var i = 0; i < elementSet.items.length; i++) {
        elementSet.items[i].attr({
            "fill-opacity": value,
            "stroke-opacity": value
        });
    }
}

function DrawConnectionLine(leftItem, rightItem) {
    var endPointItemType = leftItem.type;
    var endPointItem = leftItem.coord;
    var startPointItemType = rightItem.type;
    var startPointItem = rightItem.coord;

    var line = cnvs.set();

    var endX;
    var startX;
    if (endPointItemType == "fiber") {
        if (endPointItem.x < cnvs.width / 2) {
            endX = endPointItem.x + 54;
            var extra = cnvs.path("M" + endPointItem.x + "," + endPointItem.y + " L" + (endX + 1) + "," + endPointItem.y).data("isExtra", true);
            extra.toFront();
            line.push(extra);
        }
        else {
            endX = endPointItem.x - 58;
            var extra = cnvs.path("M" + endPointItem.x + "," + endPointItem.y + " L" + (endX - 1) + "," + endPointItem.y).data("isExtra", true);
            extra.toFront();
            line.push(extra);
        }
    }
    else if (endPointItemType == "splitter") {
        if (!leftItem.isInput) {
            endX = endPointItem.x + 25;
            var extra = cnvs.path("M" + endPointItem.x + "," + endPointItem.y + " L" + (endX + 1) + "," + endPointItem.y).data("isExtra", true);
            extra.toFront();
            line.push(extra);
        }
        else {
            endX = endPointItem.x - 25;
            var extra = cnvs.path("M" + endPointItem.x + "," + endPointItem.y + " L" + (endX - 1) + "," + endPointItem.y).data("isExtra", true);
            extra.toFront();
            line.push(extra);
        }
    }

    if (startPointItemType == "fiber") {
        if (startPointItem.x < cnvs.width / 2) {
            startX = startPointItem.x + 54;
            var extra = cnvs.path("M" + startPointItem.x + "," + startPointItem.y + " L" + (startX + 1) + "," + startPointItem.y).data("isExtra", true);
            extra.toFront();
            line.push(extra);
        }
        else {
            startX = startPointItem.x - 58;
            var extra = cnvs.path("M" + startPointItem.x + "," + startPointItem.y + " L" + (startX - 1) + "," + startPointItem.y).data("isExtra", true);
            extra.toFront();
            line.push(extra);
        }
    }
    else if (startPointItemType == "splitter") {
        if (!rightItem.isInput) {
            startX = startPointItem.x + 25;
            var extra = cnvs.path("M" + startPointItem.x + "," + startPointItem.y + " L" + (startX + 1) + "," + startPointItem.y).data("isExtra", true);
            extra.toFront();
            line.push(extra);
        }
        else {
            startX = startPointItem.x - 25;
            var extra = cnvs.path("M" + startPointItem.x + "," + startPointItem.y + " L" + (startX - 1) + "," + startPointItem.y).data("isExtra", true);
            extra.toFront();
            line.push(extra);
        }
    }

    var main = cnvs.path("M" + endX + "," + endPointItem.y + "  L" + startX + "," + startPointItem.y).data("isMain", true);
    main.toBack();
    line.push(main);

    line.attr({ "stroke-width": 4, "stroke": "#9DB28E" });

    line.hover(function () {
        HoverHandler_ConnectionLine(line, leftItem, rightItem, true);

    }, function () {
        HoverHandler_ConnectionLine(line, leftItem, rightItem, false);
    });

    line.click(function () {
        if (window.confirm("Вы уверены, что хотите удалить соединение?")) {
            RemoveFromConnectionArray(allConnections, line);
            line.remove();
        }
    });

    return line;
}

function HoverHandler_ConnectionLine(line, leftItem, rightItem, isHoverOn) {
    var strokeLine = isHoverOn ? "#E9B28E" : "#9DB28E";
    var colorSetStroke = isHoverOn ? "#E9B28E" : "black";
    var colorSetStrokeWidth = isHoverOn ? 2 : 1;

    line.attr({ "stroke": strokeLine });
    if (leftItem.colorSet) {
        leftItem.colorSet.attr({ "stroke": colorSetStroke, "stroke-width": colorSetStrokeWidth });
    }
    if (rightItem.colorSet) {
        rightItem.colorSet.attr({ "stroke": colorSetStroke, "stroke-width": colorSetStrokeWidth });
    }

    HighlightConnectionLinesAndSplitterOnHover(line, isHoverOn);
}

function saveConnectPoint(stay) {
    var data = {};
    if (!cid)
        cid = guid();

    data["id"] = cid;
    data["name"] = $("#connect_name").html();
    data["type"] = $("#connect_type").html();
    if (data["name"] == editPlaceholder)
        data["name"] = "";
    if (data["type"] == editPlaceholder)
        data["type"] = "";
    data["id_support"] = pointId;


    $.ajax({
        method: "POST",
        url: "include/connection_controller.php",
        data: {
            "op": "save_connectpoint",
            "data": JSON.stringify(data)
        }
    }).done(function (response) {
        var result = JSON.parse(response);
        if (result.success) {
            if ($("#connection_window").is(":visible")) {
                saveConnections();
            }
            parent.$("body").trigger({
                type: "connectionSaved",
                close: !stay
            });
            return;
        } else
            alert("Ошибка при сохранении точки: " + result.error);
    });
}

function saveConnections() {
    var data = {};
    data["cid"] = cid;
    data["point"] = pointId;
    data["connections"] = [];
    data["splitters"] = [];

    for (var i = 0; i < allConnections.length; i++) {
        data["connections"].push({
            "left": allConnections[i].leftUnit,
            "right": allConnections[i].rightUnit
        });
    }

    for (var i = 0; i < allSplitters.length; i++) {
        data["splitters"].push({
            splitterID: allSplitters[i].splitterID,
            typeID: allSplitters[i].typeID
        });
    }

    $.ajax({
        method: "POST",
        url: "include/connection_controller.php",
        data: {
            "op": "save_connections",
            "data": JSON.stringify(data)
        }}).done(function (response) {
        var result = JSON.parse(response);
        if (!result.success) {
            window.alert(result.error);
        }
        else {
            window.alert("Изменения успешно сохранены.");
        }
    });
}

function connectRowBound(nRow, aData, iDataIndex) {
    $("td:eq(2)", nRow).html("<a href='javascript:void(0)' class='connect-edit-link' >Редактировать</a>");
    $(nRow).attr("id", aData[2]);
}

function initConnectionTable() {
    $("#connection_points").dataTable({
        "bPaginate": false,
        "bLengthChange": false,
        "bFilter": true,
        "bSort": false,
        "bInfo": false,
        "bAutoWidth": false,
        "bFilter": false,
        "bInfo": false,
        "fnCreatedRow": connectRowBound,
        "oLanguage": {
            "sEmptyTable": "Нет ни одной точки соединения"
        },
        "aoColumns": [
            {
                "sClass": "ui-widget-content"
            },
            {
                "sClass": "ui-widget-content"
            },
            {
                "sClass": "ui-widget-content"
            }
        ]
    });
}

function mergeCables(s1, s2) {
    var canMerge = true;
    $.ajax(
        {
            async: false,
            method: "POST",
            url: "include/connection_controller.php",
            data: {
                segment1: s1,
                segment2: s2,
                pointID: pointId,
                op: "can_merge_segments"
            }
        }).done(function (response) {
            var result = JSON.parse(response);
            canMerge = result.success;
        })

    if (canMerge) {
        var data = {
            segment1: s1,
            segment2: s2,
            point: pointId,
            id: guid()
        }
        $.ajax({
            method: "POST",
            url: "include/connection_controller.php",
            data: {
                op: "merge_segments",
                data: JSON.stringify(data)
            }
        }).done(function (response) {
            var result = JSON.parse(response);
            if (result.success) {
                paper.clear();
                initConnections(pointId, cid, false);
            } else {
                alert("Ошибка: " + result.error);
            }
        });
    }
    else {
        alert("Эти сегменты уже участвуют в соединениях.\nВыберите другие сегменты, либо удалите существующие соединения");
    }
}

function parseConnectionResponse(response) {
    var result = JSON.parse(response);
    if (result.success) {
        paper.clear();
        initConnections(pointId, cid, false);
    } else {
        alert("Ошибка: " + result.error);
    }
}

function deleteConnection() {
    if (confirm("Вы уверены, что хотите удалить соединение?")) {
        $.ajax({
            method: "POST",
            url: "include/connection_controller.php",
            data: {
                op: "delete_connection",
                id: conId
            }
        }).done(parseConnectionResponse);
    }
}

function DeleteConnectionBetweenSegments(id1, id2) {
    if (confirm("Вы уверены, что хотите удалить соединение?")) {
        $.ajax({
            method: "POST",
            url: "include/connection_controller.php",
            data: {
                op: "delete_connection_between_segments",
                segment1: id1,
                segment2: id2
            }
        }).done(parseConnectionResponse);
    }
}

function deleteConnectPoint() {
    if (cid) {
        if (!confirm("Вы уверены, что хотите удалить точку соединения?\nЭто приведет к удалению всех принадлежащих ей соединений.")) return;
        $.ajax({
            method: "POST",
            url: "include/connection_controller.php",
            data: {
                op: "delete_connect_point",
                id: cid
            }
        }).done(function (response) {
            var result = JSON.parse(response);
            if (result.success)
                parent.$("body").trigger("connectPointRemoved");
            else
                alert("Ошибка: " + result.error);
        });
    }
}

